package com.rpc.server.framework;

import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Method;
import java.net.Socket;
import java.util.Map;

/**
 * com.rpc.server
 *
 * @author humdeef
 * @since 2019-07-17
 */
public class SocketTask implements Runnable {
  Socket socket;
  Map<String, Object> serverList;

  public SocketTask(Socket socket, Map<String, Object> serverList) {
    this.socket = socket;
    this.serverList = serverList;
  }

  @Override
  public void run() {
    // 报文格式
    // 第一个参数为暴露的接口名(string)
    // 第二个参数 方法名字（string）
    // 第三个参数 参数类型列表(Class<?>[])
    // 第四个参数 参数值列表（Object[]）)
    try (ObjectInputStream deserializer = new ObjectInputStream(socket.getInputStream());
        ObjectOutputStream serializer = new ObjectOutputStream(socket.getOutputStream())) {
      // 解析客户端传输给服务端的数据
      String interfaceName = deserializer.readUTF();
      String methodName = deserializer.readUTF();
      Class<?>[] parameterTypes = (Class<?>[]) deserializer.readObject();
      Object[] parameters = (Object[]) deserializer.readObject();

      // 通过服务列表查询暴露的接口对应的实例
      Object instance = serverList.get(interfaceName);
      if (instance == null) {
        throw new RuntimeException("调用接口 " + interfaceName + " 失败.");
      }
      //获取到需要反射调用的方法
      Method method = instance.getClass().getDeclaredMethod(methodName, parameterTypes);
      // 反射调用方法
      Object result = method.invoke(instance, parameters);
      serializer.writeObject(result);
    } catch (Exception e) {
      e.printStackTrace();
    }

  }
}
